﻿using System;
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.EventSystems;

namespace UBlockly.Scriptable
{
    public abstract class ILFunc
    {
        protected string functionName;
        protected ILFunc[] paramILFunc;
        public string FunName => functionName;

        public ILFunc(string functionName)
        {
            this.functionName = functionName;
        }

        public void SetParamCount(int count)
        {
            paramILFunc = new ILFunc[count];
        }

        public void SetParam(int index,ILFunc func)
        {
            paramILFunc[index] = func;
        }

        public virtual IVarObject Excute(int blockEntryHash = 0)
        {
            List<object> plist = new List<object>();
            if (paramILFunc != null)
            {
                for (int i = 0; i < paramILFunc.Length; i++)
                {
                    plist.Add(paramILFunc[i].Excute(blockEntryHash));
                }
            }
            return ILTranslate.ExF($"{blockEntryHash}${FunName}", plist.ToArray());
        }
    }

    //内置的默认参数函数,只返回获取的内容
    public sealed class DefaultParamIlFunc : ILFunc
    {
        private object defaultParam;
        private Func<object> paramCompontentGetter;
        public DefaultParamIlFunc(string funcName,Func<object> paramGetter) :base(funcName)
        {
            paramCompontentGetter = paramGetter;
        }

        public DefaultParamIlFunc(string funcName, object defaultValue) : base(funcName)
        {
            defaultParam = defaultValue;
        }
        
        public override IVarObject Excute(int blockEntryHash)
        {
            blockEntryHash = Constant.DefaultBlockParamHash;
            object targetValue = paramCompontentGetter != null ? paramCompontentGetter():defaultParam;
            return ILTranslate.ExF($"{blockEntryHash}${FunName}", targetValue);
        }

        public IVarObject GetDefaultValue()
        {
            return Excute(0);
        }
    }
    //普通块函数
    public class BlockILFunc : ILFunc
    {
        protected VoidR targetResult;

        public BlockILFunc(string funcName) : base(funcName)
        { }

        public virtual void Excute(int blockEntryHash, System.Action callback)
        {
            targetResult = (VoidR)Excute(blockEntryHash);
            if(callback != null)
                targetResult.SetConitnue(callback);
        }
    }
    //复合块函数
    public class ComplexBlockILFunc : BlockILFunc
    {
        private List<ILFunc> funcList;

        public ComplexBlockILFunc(string[] treeNodeStrArray) : base("")
        {
            funcList = new List<ILFunc>(treeNodeStrArray.Length);
            for (int i = 0; i < treeNodeStrArray.Length; i++)
            {
                //把一个组合的块生成一颗运行时树，得到运行时树函数
                var func = SerializeTreeNode.FromStr(treeNodeStrArray[i]).ToRuntimeILFunc();
                funcList.Add(func);
            }
        }

        public override IVarObject Excute(int blockEntryHash)
        {
            if(funcList.Count != 1)
                throw new System.Exception("ComplexBlockILFunc unknow error");
            return funcList[0].Excute(blockEntryHash);
        }

        public override void Excute(int blockEntryHash, Action callback)
        {
            var count = funcList.Count;
            for (int i = 0; i < count; i++)
            {
                funcList[i].Excute(blockEntryHash);
                if (i == count - 1 && callback != null)
                {
                    targetResult = new VoidR();
                    targetResult.SetConitnue(callback);
                }
            }
        }
    }
}
